﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace TNCGameEngine.Scripting
{

    public interface IProperty
    {

        bool GetPropertyValue(string name, out object value);

        void SetPropertyValue(string name, object value);

        bool ReplacePropertyValue(string name, object value);

    }

    public class ScriptManager
    {

        #region "Properties"
                
        private string rootDirectory = string.Empty;
        public string RootDirectory
        {
            get { return this.rootDirectory; }
            set { this.rootDirectory = (value.EndsWith("\\")) ? value.Remove(value.Length - 2, 2) : value; }
        }

        private string fileExtension = "tnc";
        public string FileExtension
        {
            get { return this.fileExtension; }
            set { this.fileExtension = value.ToLower(); }
        }

        private List<string> assemblies = null;
        public List<string> LinkedAssemblies
        {
            get { return this.assemblies; }
            set { this.assemblies = value; }
        }

        #endregion

        #region "Variables"
        
        internal static Dictionary<string, Type> Types = new Dictionary<string, Type>();

        #endregion

        #region "Contructors"

        public ScriptManager()
        {
            // do nothing
        }

        public ScriptManager(string root)
            :this()
        {
            this.rootDirectory = root;
        }

        #endregion

        #region "Methods"

        public void InitializeScripting()
        {
            Script.InitializeScripting(this);
            this.CacheReferencedAssemblies();
            this.AddPrimitiveTypes();
        }

        private void CacheReferencedAssemblies()
        {
            Assembly entryAssembly = Assembly.GetEntryAssembly();
            AssemblyName[] names = entryAssembly.GetReferencedAssemblies();
            this.assemblies = new List<string>(names.Length+1);
            this.assemblies.Add(entryAssembly.GetName().ToString());
            foreach (AssemblyName name in names)
            {
                this.assemblies.Add(name.ToString());
            }
        }

        private void AddPrimitiveTypes()
        {
            
            ScriptManager.Types.Add("object", typeof(object));
            ScriptManager.Types.Add("string", typeof(string));
            ScriptManager.Types.Add("char", typeof(char));
            ScriptManager.Types.Add("byte", typeof(byte));
            ScriptManager.Types.Add("sbyte", typeof(sbyte));
            ScriptManager.Types.Add("ushort", typeof(ushort));
            ScriptManager.Types.Add("short", typeof(short));
            ScriptManager.Types.Add("uint", typeof(uint));
            ScriptManager.Types.Add("int", typeof(int));
            ScriptManager.Types.Add("ulong", typeof(ulong));
            ScriptManager.Types.Add("long", typeof(long));
            ScriptManager.Types.Add("float", typeof(float));
            ScriptManager.Types.Add("double", typeof(double));
            ScriptManager.Types.Add("bool", typeof(bool));

        }

        #endregion

    }

}
